﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Microsoft.Deployment.Compression.Cab;

using Noris.Schedule.Support;
using Noris.Schedule.Support.Parser;
using Noris.Tools.DbManager.Components;
using Noris.Tools.DbManager.Data;
using System.IO;

namespace Noris.Tools.DbManager.Forms
{
    public partial class MainForm : Form
    {
		#region Konstrukce a vnitřní eventy
        public MainForm()
        {
            InitializeComponent();
            this.Init();
            this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed);
        }
        void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            WorkingThread.Close();
        }
        protected void Init()
        {
            this._DbProfileList.SizeChanged += new EventHandler(_DbList_SizeChanged);

            WinReg.SetRootDefaultFolder(Microsoft.Win32.RegistryHive.CurrentUser, "Software\\DjSoft\\DbManager");
            string norisConfigFile = WinReg.ReadString("Config", "NorisFile", "");
            if (String.IsNullOrEmpty(norisConfigFile))
                norisConfigFile = @"C:\inetpub\wwwroot\Noris43\Noris\noris.config";
            this.NorisConfigFile = norisConfigFile;

            this.CabinetData = new Cabinet();
			this.PrepareCombo();

            this.Load += new EventHandler(MainForm_Load);
        }
        void MainForm_Load(object sender, EventArgs e)
        {
            // Zadám úkoly, které se budou provádět na pozadí, poměrně rychle skončím a nechám otevřít okno:
            //  (nelze provádět v konstruktoru = v metodě Init(), protože to ještě okno nemá navázaný thread vlastníka, a špatně by chodily invokace do popředí).
            this.ToolSetEnable(ToolbarAvailableItem.MixStandardUI);
            this.LoadNorisConfigFile();
            this.LoadPackages();
        }
        void _DbList_SizeChanged(object sender, EventArgs e)
        {
            this._DbProfileList.Columns[0].Width = this._DbProfileList.Width - SystemInformation.VerticalScrollBarWidth - this._DbProfileList.Columns[1].Width - 8;

        }
        private void _BtnNoris_Click(object sender, EventArgs e)
        {
            string configFile = this.NorisConfigFile;
            string path = null;
            if (Noris.Schedule.Support.SystemFileDialog.GetExistingFile(ref configFile, ref path, "Config files (*.config)|*.config|All files (*.*)|*.*", ".config", "Select Noris.config file"))
            {
                WinReg.WriteString("Config", "NorisFile", configFile);
                this.NorisConfigFile = configFile;
                this.LoadNorisConfigFile();
            }
        }
        private void _RunBtn_Click(object sender, EventArgs e)
		{
			this.RunScripting();
		}

		#endregion
        #region Toolbar - řízení Enabled pro prvky
        /// <summary>
        /// Nastaví Enabled na prvky UI podle parametru.
        /// Je možno volat z libovolného threadu.
        /// </summary>
        /// <param name="items"></param>
        protected void ToolSetEnable(ToolbarAvailableItem items)
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new Action<ToolbarAvailableItem>(this.ToolSetEnable), items);
            else
            {
                this._BtnNoris.Enabled = ((items & ToolbarAvailableItem.NorisConfig) != 0);
                this._VersionCombo.Enabled = ((items & ToolbarAvailableItem.PackagesCombo) != 0);
                this._PackageCombo.Enabled = ((items & ToolbarAvailableItem.PackagesCombo) != 0);
                this._StopBtn.Enabled = ((items & ToolbarAvailableItem.StopButton) != 0);
                this._PauseBtn.Enabled = ((items & ToolbarAvailableItem.PauseButton) != 0);
                this._RunBtn.Enabled = ((items & ToolbarAvailableItem.RunButton) != 0);
                this._DbProfileList.Enabled = ((items & ToolbarAvailableItem.DbProfiles) != 0);
            }
        }
        [Flags]
        protected enum ToolbarAvailableItem
        {
            None = 0,
            NorisConfig = 0x0001,
            PackagesCombo = 0x0002,
            StopButton = 0x0100,
            PauseButton = 0x0200,
            RunButton = 0x0400,
            DbProfiles = 0x1000,
			MixStandardUI = NorisConfig | PackagesCombo | RunButton | DbProfiles,
			MixLoadingData = NorisConfig | PackagesCombo | DbProfiles,
            MixRunning = StopButton | PauseButton,
            MixPause = StopButton | RunButton,
            MixAll = NorisConfig | PackagesCombo | StopButton | PauseButton  | RunButton | DbProfiles,
        }
        #endregion
        #region Noris Profiles - Load
        protected void LoadNorisConfigFile()
        {
            string norisConfigFile = this.NorisConfigFile;
            this._BtnNoris.ToolTipText = "Noris.config file:\r\n" + norisConfigFile;
            Steward.AppConfig.ConfigFileExplicit = norisConfigFile;      // Vložím explicitní jméno configu

            // Načítání noris configu provedeme na pozadí:
            WorkingThread.AddItem(this.LoadNorisConfigFileBgr, this.LoadNorisConfigFileError, this.LoadNorisConfigFileDone);
        }
        private void LoadNorisConfigFileBgr()
        {
			this.ToolSetEnable(ToolbarAvailableItem.MixLoadingData);
            this._StatusStrip.MainText = "Loading Noris.config...";

			// Metoda běží na pozadí: ze Stewarda přečte seznam profilů, což vyvolá fyzické čtení configu:
            this.ConnectProfiles = Steward.AppConfig.DbProfileList;

			this.ToolSetEnable(ToolbarAvailableItem.MixStandardUI);
        }
        private void LoadNorisConfigFileError(Exception exc)
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new Action<Exception>(this.LoadNorisConfigFileError), exc);
            else
            {
                if (this._StatusStrip.ProgressBarVisible)
                    this._StatusStrip.ProgressHide();
                this._StatusStrip.MainText = "Error: " + exc.Message;
                this._RtfText.Rtf = GetRtfText("Chyba při načítání souboru Noris.config " + this.SelectedCabinetInfo.CabFileInfo.FullName, exc.Message, exc.StackTrace);
            }
        }
        private void LoadNorisConfigFileDone()
        {
			// Metoda je vyvolána z threadu na pozadí, ale pracuje s daty v GUI:
            if (this.InvokeRequired || this._DbProfileList.InvokeRequired)
                this.BeginInvoke(new Action(this.LoadNorisConfigFileDone));
            else
            {
				this._StatusStrip.MainText = "Processing Noris.config...";

				List<ConnectProfile> profiles = this.ConnectProfiles;
                string eol = Environment.NewLine;
                this._DbProfileList.Items.Clear();
                this._DbProfileList.Groups.Clear();

                Dictionary<string, ListViewGroup> groups = new Dictionary<string, ListViewGroup>();
                foreach (ConnectProfile profile in profiles)
                {
                    string dataSource = profile.DataSource.Trim().ToLower();
                    ListViewGroup group;
                    if (!groups.TryGetValue(dataSource, out group))
                    {
                        group = new ListViewGroup(dataSource, profile.DataSource);
                        group.HeaderAlignment = HorizontalAlignment.Left;
                        groups.Add(dataSource, group);
                        this._DbProfileList.Groups.Add(group);
                    }

                    ListViewItem item = new ListViewItem(profile.ProfileName, group);
                    item.ToolTipText = "Profile: " + profile.ProfileName + eol +
                                       "Server: " + profile.DataSource + eol +
                                       "Database: " + profile.SourceDatabase;
					item.Tag = profile;
                    this._DbProfileList.Items.Add(item);
                }

				this._StatusStrip.MainText = "Ready";
			}
        }
		/// <summary>
		/// Seznam DB profilů, které jsou aktuálně vybrané
		/// </summary>
		internal List<ConnectProfile> SelectedConnectProfiles
		{
			get
			{
				if (this.InvokeRequired)
					return (List<ConnectProfile>)this.Invoke(new Func<List<ConnectProfile>>(this._GetSelectedConnectProfiles));
				else
					return this._GetSelectedConnectProfiles();
			}
		}
		/// <summary>
		/// Vrací 
		/// </summary>
		/// <returns></returns>
		private List<ConnectProfile> _GetSelectedConnectProfiles()
		{
			List<ConnectProfile> result = new List<ConnectProfile>();
			ListView.CheckedListViewItemCollection checkedItems = this._DbProfileList.CheckedItems;
			foreach (ListViewItem selItem in checkedItems)
			{
				ConnectProfile profile = selItem.Tag as ConnectProfile;
				if (profile != null)
					result.Add(profile);
			}
			return result;
		}
        public string NorisConfigFile { get; set; }
        public List<ConnectProfile> ConnectProfiles { get; set; }
        #endregion
        #region Packages - Load
		/// <summary>
		/// Zajistí načtení seznamu balíčků do vnitřních polí a do toolbaru
		/// </summary>
        protected void LoadPackages()
        {   // Načítání souborů balíčků provedeme na pozadí
            WorkingThread.AddItem(this.LoadPackagesBgr, this.LoadPackagesError, this.LoadPackagesDone);
            this._RtfText.Rtf = GetRtfText("Probíhá načítání balíčků...");
        }
		/// <summary>
		/// Výkonná metoda načítání seznamu balíčků, prováděná na pozadí
		/// </summary>
		protected void LoadPackagesBgr()
		{	// Thread na pozadí - výkonná metoda, načítání balíčků:
			this.ToolSetEnable(ToolbarAvailableItem.MixLoadingData);
			this._StatusStrip.MainText = "Loading package file list...";
			string[] paths = this.FindPackagePath();
            this.PackagesList = PackageSet.ReadContentOfDirs(paths);
			this.ToolSetEnable(ToolbarAvailableItem.MixStandardUI);
		}
        protected void LoadPackagesError(Exception exc)
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new Action<Exception>(this.LoadPackagesError), exc);
            else
            {
                if (this._StatusStrip.ProgressBarVisible)
                    this._StatusStrip.ProgressHide();
                this._StatusStrip.MainText = "Error: " + exc.Message;
                this._RtfText.Rtf = GetRtfText("Chyba při načítání seznamu balíčků " + this.SelectedCabinetInfo.CabFileInfo.FullName, exc.Message, exc.StackTrace);
            }
        }
		/// <summary>
		/// Metoda volaná z pozadí po dokončení načítání balíčků
		/// </summary>
        protected void LoadPackagesDone()
        {
			if (this.InvokeRequired)
				this.BeginInvoke(new Action<bool>(this.LoadPackagesAddToCombo), false);
			else
				this.LoadPackagesAddToCombo(false);
        }
		/// <summary>
		/// Uloží do comba s verzemi soupis verzí.
		/// </summary>
		/// <param name="allHotPatches"></param>
		protected void LoadPackagesAddToCombo(bool allHotPatches)
		{
			if (this._VersionCombo.IsDisposed) return;
			this.FillComboVersion();
		}
		/// <summary>
		/// Metoda vrátí seznam adresářů, odkud se budou balíčky načítat.
		/// Reaguje na aktuální situaci a na umístění aplikace, na stav - co je pro ni dostupné
		/// </summary>
		/// <returns></returns>
		protected string[] FindPackagePath()
		{
			List<string> paths = new List<string>();
			if (System.IO.Directory.Exists(@"C:\Lcs\Tools\NorisPrivate\"))
			{
				FindPackagePathAddOne(paths, @"C:\Lcs\Tools\NorisPrivate\");
			}
			else if (System.IO.Directory.Exists(@"\\centauri\Verze\"))
			{
				FindPackagePathAddOne(paths, @"\\centauri\Verze\42\Private\");
				FindPackagePathAddOne(paths, @"\\centauri\Verze\43\Private\");
			}
			return paths.ToArray();
		}
		/// <summary>
		/// Pokud adresář existuje, přidá jej do seznamu
		/// </summary>
		/// <param name="paths"></param>
		/// <param name="path"></param>
		protected void FindPackagePathAddOne(List<string> paths, string path)
		{
			if (System.IO.Directory.Exists(path))
				paths.Add(path);
		}
        #endregion
        #region CabFiles - správa
        protected void SelectCabinetFile(string fileName)
        {
            this.SelectedCabinetInfo = this.CabinetData.SelectCabinetFile(fileName);
            this.LoadCabinetContent(NORIS_SCRIPTS_CAB);
        }
        private void LoadCabinetContent(string cabItem)
        {
            if (this.SelectedCabinetInfo == null || !this.SelectedCabinetInfo.Exists) return;

            // Načítání obsahu balíčku provedeme na pozadí
            this.SelectedCabinetItem = cabItem;
            WorkingThread.AddItem(this.LoadCabinetContentBgr, this.LoadCabinetContentError, this.LoadCabinetContentDone);
            this._RtfText.Rtf = GetRtfText("Probíhá načítání obsahu balíčku " + this.SelectedCabinetInfo.CabFileInfo.FullName + " [" + this.SelectedCabinetItem + "]");
        }
        private void LoadCabinetContentBgr()
        {   // Thread na pozadí:
			this.ToolSetEnable(ToolbarAvailableItem.MixLoadingData);
            this.SelectedCabinetContent = this.SelectedCabinetInfo.GetInnerFiles(this.SelectedCabinetItem, this.CabProgressHandler);
			this.ToolSetEnable(ToolbarAvailableItem.MixStandardUI);
        }
        private void CabProgressHandler(object sender, Microsoft.Deployment.Compression.ArchiveProgressEventArgs args)
        {
			if (!this._StatusStrip.ProgressBarVisible)
			{
				this._StatusStrip.MainText = "Unpack: " + this.SelectedCabinetInfo.CabFileInfo.Name;
                this._StatusStrip.ProgressShowAll();
			}

            StatusData data = new StatusData();
            data.ProgressCaptionText = args.CurrentFileName;
            data.ProgressBarRatio = (float)args.FileBytesProcessed / (float)args.TotalFileBytes;
            data.ProgressCountText = args.CurrentFileNumber.ToString() + "/" + args.TotalFiles.ToString();
            this._StatusStrip.CurrentStatusData = data;

			float progres1 = (float)args.FileBytesProcessed / (float)args.TotalFileBytes;
			float progress = ((float)args.CurrentFileNumber + progres1) / (float)args.TotalFiles;
			float progrest = ((float)args.FileBytesProcessed + progres1) / (float)args.TotalFileBytes;
			string count = args.CurrentFileNumber.ToString() + "/" + args.TotalFiles.ToString();
			// this.StatusProgressShow(args.CurrentFileName, progrest, count, null);
        }
        private void LoadCabinetContentError(Exception exc)
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new Action<Exception>(this.LoadCabinetContentError), exc);
            else
            {
                if (this._StatusStrip.ProgressBarVisible)
                    this._StatusStrip.ProgressHide();
                this._StatusStrip.MainText = "Error: " + exc.Message;
                this._RtfText.Rtf = GetRtfText("Chyba při načítání balíčku " + this.SelectedCabinetInfo.CabFileInfo.FullName, exc.Message, exc.StackTrace);
            }
        }
        private void LoadCabinetContentDone()
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new Action(this.LoadCabinetContentDone));
            else
            {
                if (this._StatusStrip.ProgressBarVisible)
                    this._StatusStrip.ProgressHide();
                int sqlCnt = this.SelectedCabinetContent.Count(fsi => String.Equals(fsi.Extension, ".sql", StringComparison.InvariantCultureIgnoreCase));
                this._StatusStrip.MainText = this.SelectedCabinetInfo.CabFileInfo.Name + "; " + sqlCnt.ToString() + " scripts";
                this._RtfText.Rtf = GetRtfText("Balíček " + this.SelectedCabinetInfo.CabFileInfo.FullName + " [" + this.SelectedCabinetItem + "] byl načten, obsahuje " + sqlCnt.ToString() + " skriptů.");
			}
        }
        protected void CabinetDispose()
        {
            this.CabinetData.Dispose();
        }
        /// <summary>
        /// Podpora pro práci s CAB
        /// </summary>
        private Cabinet CabinetData { get; set; }
        /// <summary>
        /// Aktuální CAB soubor
        /// </summary>
        private CabinetInfo SelectedCabinetInfo { get; set; }
        /// <summary>
        /// Aktuální soubor v rámci CAB souboru
        /// </summary>
        private string SelectedCabinetItem { get; set; }
        /// <summary>
        /// Obsažené soubory v SelectedCabinetInfo : SelectedCabinetItem
        /// </summary>
        private List<FileSystemInfo> SelectedCabinetContent { get; set; }
        protected const string NORIS_SCRIPTS_CAB = "Noris_Scripts.cab";
        #endregion
		#region Vlastní skriptování databáze
		/// <summary>
		/// Metoda, která spustí skriptování.
		/// Metoda se spouští z GUI (z buttonu), připraví data a zajistí provedení akce na pozadí
		/// </summary>
		protected void RunScripting()
		{
			// DbProfile:
			List<ConnectProfile> profiles = this.SelectedConnectProfiles;
			if (profiles.Count == 0)
			{
				Noris.Schedule.Support.Core.Dialog.ShowWarning(MessageInfo.Get("Select (check) at least one database profile in list."));
				return;
			}

			// Developments:
			List<FileSystemInfo> scripts = this.SelectedCabinetContent;
			CabinetInfo cabinetInfo = this.SelectedCabinetInfo;
			DevelopmentData developments = DevelopmentData.CreateForFiles(this.SelectedPackageItem, this.SelectedCabinetInfo, scripts);
			if (!developments.ContainAnyScript)
			{
				Noris.Schedule.Support.Core.Dialog.ShowWarning(MessageInfo.Get("Selected package does not contain any development with script."));
				return;
			}

			// Sbalíme data a odešleme je ke zpracování na pozadí:
			ScriptorData scriptorData = new ScriptorData();
			scriptorData.Profiles = profiles;
			scriptorData.Development = developments;
			WorkingThread.AddItem(this.RunScriptingBgr, scriptorData, this.RunScriptingProgress, this.RunScriptingError, this.RunScriptingDone);
		}
		private void RunScriptingBgr(WorkingThreadArgs workingData)
		{
			ScriptorData scriptorData = workingData.Data as ScriptorData;
			if (scriptorData == null)
				throw new ArgumentException("Invalid argument: WorkingThreadArgs.Data is not type ScriptorData, as expected.", "WorkingThreadArgs.Data");

			this.ToolSetEnable(ToolbarAvailableItem.MixRunning);
			Scriptor.RunScript(scriptorData);
		}
		private void RunScriptingProgress(WorkingThreadProgressArgs progress)
		{
			if (!this._StatusStrip.ProgressBarVisible)
			{
				this._StatusStrip.MainText = "Scripting";
				this._StatusStrip.ProgressShowAll();
			}

			this._StatusStrip.SetStatusBarData(new StatusData(progress.ProgressData));
		}
		private void RunScriptingError(Exception exc)
		{
		}
		private void RunScriptingDone()
		{
			if (this._StatusStrip.ProgressBarVisible)
			{
				this._StatusStrip.MainText = "Ready";
				this._StatusStrip.ProgressHide();
			}
			
			this.ToolSetEnable(ToolbarAvailableItem.MixStandardUI);
		}
		#endregion
		#region Data (Dictionary, SelectedItems)
		/// <summary>
		/// Výsledný seznam balíčků, odpovídá 1:1 nabídce v toolbaru
		/// </summary>
		internal List<PackageSet> PackagesList;
		/// <summary>
		/// Aktuálně vybraná sada balíčků (shodná verze)
		/// </summary>
		internal PackageSet SelectedPackageSet;
		/// <summary>
		/// Aktuálně vybraný balíček (soubor)
		/// </summary>
		internal PackageItem SelectedPackageItem;
        #endregion
		#region Fyzická práce s combo boxy
		/// <summary>
		/// Připraví combo boxy při inicializaci
		/// </summary>
		protected void PrepareCombo()
		{
			this._VersionCombo.Items.Clear();
			this._VersionCombo.Items.Add("Loading...");
			this._VersionCombo.SelectedIndex = 0;
			this._PackageCombo.Items.Clear();
			this._PackageCombo.Items.Add("Loading...");
			this._PackageCombo.SelectedIndex = 0;

			this._VersionCombo.SelectedIndexChanged += new EventHandler(_VersionCombo_SelectedIndexChanged);
			this._PackageCombo.SelectedIndexChanged += new EventHandler(_PackageCombo_SelectedIndexChanged);
		}
		/// <summary>
		/// Eventhandler po změně položky Combo: Verze
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		void _VersionCombo_SelectedIndexChanged(object sender, EventArgs e)
		{
			object selectedItem = this._VersionCombo.SelectedItem;
			if (selectedItem == null) return;
			this.SelectedPackageSet = selectedItem as PackageSet;
            this.VersionSelectAfter();
		}
		/// <summary>
		/// Eventhandler po změně položky Combo: Package
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		void _PackageCombo_SelectedIndexChanged(object sender, EventArgs e)
		{
			object selectedItem = this._PackageCombo.SelectedItem;
			if (selectedItem == null) return;
			this.SelectedPackageItem = selectedItem as PackageItem;
            this.PackageSelectAfter();
		}
        /// <summary>
        /// Po výběru verze
        /// </summary>
        private void VersionSelectAfter()
        {
            this.FillComboPackage();
        }
        /// <summary>
        /// Po výběru souboru
        /// </summary>
        private void PackageSelectAfter()
        {
            string name = "";
            string file = "";
            string info = "";
            if (this.SelectedPackageItem != null)
            {
                System.IO.FileInfo fileInfo = this.SelectedPackageItem.FileInfo;
                name = fileInfo.Name;
                file = fileInfo.FullName;
                info = "File: " + file + Environment.NewLine +
                    "Time: " + fileInfo.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
            }
            this.SelectCabinetFile(file);
            this._StatusStrip.MainText = name;
            this._StatusStrip.MainTextTooltip = info;
            this._PackageCombo.ToolTipText = info;
        }
		/// <summary>
		/// Naplní položky do combo this._VersionCombo z položek seznamu this.PackagesList
		/// </summary>
		protected void FillComboVersion()
		{
			this._StatusStrip.MainText = "Processing package file list...";

			this._VersionCombo.Items.Clear();
			foreach (PackageSet set in this.PackagesList)
				this._VersionCombo.Items.Add(set);

			this._StatusStrip.MainText = "Ready";

			if (this.PackagesList.Count > 0)
				this._VersionCombo.SelectedIndex = 0;
		}
		/// <summary>
		/// Naplní položky do combo this._VersionCombo z položek seznamu this.PackagesList
		/// </summary>
		protected void FillComboPackage()
		{
			string name = (this.SelectedPackageItem == null ? null : this.SelectedPackageItem.Name);

			this._PackageCombo.Items.Clear();
			if (this.SelectedPackageSet == null) return;

			List<PackageItem> itemsSorted = this.SelectedPackageSet.ItemsSorted;
			int newIdx = -1;
			foreach (PackageItem item in itemsSorted)
			{
				if (name != null && item.Name == name && newIdx < 0)
					newIdx = this._PackageCombo.Items.Count;
				this._PackageCombo.Items.Add(item);
			}

			if (this.SelectedPackageSet.Items.Count > 0)
				this._PackageCombo.SelectedIndex = (newIdx < 0 ? 0 : newIdx);
		}
		#endregion
        #region RTF texty
        private string GetRtfText(string text)
        {
            using (RtfCoder rtf = new RtfCoder())
            {
                rtf.Add(RtfItem.NewSize(10), RtfItem.NewFontStyle(RtfFontStyle.Regular), RtfItem.NewText(text));
                return rtf.RtfText;
            }
        }
        private string GetRtfText(string title, string text)
        {
            using (RtfCoder rtf = new RtfCoder())
            {
                rtf.Add(RtfItem.NewSize(10), RtfItem.NewFontStyle(RtfFontStyle.Bold), RtfItem.NewText(text));
                return rtf.RtfText;
            }
        }
        private string GetRtfText(string title, string text, string note)
        {
            using (RtfCoder rtf = new RtfCoder())
            {
                rtf.Add(RtfItem.NewSize(10), RtfItem.NewFontStyle(RtfFontStyle.Bold), RtfItem.NewText(title), RtfItem.NewText(Environment.NewLine));
                rtf.Add(RtfItem.NewSize(10), RtfItem.NewFontStyle(RtfFontStyle.Regular), RtfItem.NewText(text), RtfItem.NewText(Environment.NewLine));
                rtf.Add(RtfItem.NewSize(9), RtfItem.NewFontStyle(RtfFontStyle.ItalicOnly), RtfItem.NewText(note), RtfItem.NewText(Environment.NewLine));
                return rtf.RtfText;
            }
        }
        #endregion
    }
}
